/*************************************************************
*
* M3D_CAPSULE.CPP
*
* Capsule funcionality
*
*************************************************************/
#include <stdafx.h>

//#include <ap_comm.h>
#include <m3d\m3d.h>

/*************************************************************
* m3dCAPSULE::m3dCAPSULE ()
*
*************************************************************/
m3dCAPSULE::m3dCAPSULE ()
{
   radius = -1;
}

/*************************************************************
* m3dCAPSULE::m3dCAPSULE ()
*
*************************************************************/
m3dCAPSULE::m3dCAPSULE (const m3dV &_from, const m3dV &_to, float _radius)
{
   from     =  _from;
   to       =  _to;
   radius   =  _radius;
}

/*************************************************************
* m3dCAPSULE::IsBelongPoint()
*
*************************************************************/
BOOL  m3dCAPSULE::IsBelongPoint  (const m3dV *v)
{
   if (m3dDistPointLSeg(v, &from, &to) < radius) {
      return TRUE;
   }

   return FALSE;
}

/*************************************************************
* m3dBOX::IsectCyl ()
*    Test intersection with cylinder 
*************************************************************/
BOOL  m3dCAPSULE::IsectCyl (m3dV *rayOrg, m3dV *rayDir, float distMax, float radCyl, m3dV *vClosest, float *dist, int *faceNmb)
{  
   m3dV rayFinal;
   ASSERT(radCyl > 0.001f);

   _m3dLineCombine(rayOrg, rayDir, distMax, &rayFinal);
   //Get point on the ray
   m3dV v1, v2;
   if (m3dDistLSegLSeg(rayOrg, &rayFinal, &from, &to, this->radius + radCyl, dist, &v1, &v2))   {
      m3dV dir;
      m3dSubtractVector(&v1, &v2, &dir);
      float len = m3dLengthVector(&dir);
      if (len < this->radius) {
         *vClosest = v1;
      } else {
         _m3dLineCombine(&v2, &dir, this->radius/len, vClosest);
      }
      return M3D_ISECT_YES;
   }
   return M3D_ISECT_NO;
}

/*************************************************************
* int   m3dCAPSULE::IsectRay ()
*
*    Test intersection with Ray
*
*************************************************************/
int   m3dCAPSULE::IsectRay (m3dV *rayOrg, m3dV *rayDir, float distMax, m3dV *vClosest, float *dist, int *faceNmb)
{
   m3dV rayFinal, vClosest1;

   _m3dLineCombine(rayOrg, rayDir, distMax, &rayFinal);
   //Get point on the ray
   if (m3dDistLSegLSeg(rayOrg, &rayFinal, &from, &to, radius, dist, vClosest, &vClosest1))   {
      return M3D_ISECT_YES;
   }
   return M3D_ISECT_NO;
}

/*************************************************************
* int   m3dCAPSULE::DistPoint   ()
*
*************************************************************/
int   m3dCAPSULE::DistPoint   (const m3dV *p, float distMax, m3dV *vClosest, float *dist, int *faceNmb)
{
   ASSERT(FALSE); 
   return 0;
}

/*************************************************************
* void  m3dCAPSULE::Calc  ()
*
*************************************************************/
void  m3dCAPSULE::Calc  (m3dV *pointList, int n)
{
   ASSERT(FALSE); 
}

/*************************************************************
* BOOL  m3dCAPSULE::Check (void)
*
*************************************************************/
BOOL  m3dCAPSULE::Check (void) const
{
   ASSERT(FALSE); 
   return FALSE;
}

/*************************************************************
* void  m3dCAPSULE::CalcEnclSph ()
*
*************************************************************/
void  m3dCAPSULE::CalcEnclSph (class m3dSPHERE *pSph)
{
   ASSERT(FALSE); 
}

/*************************************************************
* BOOL  m3dCAPSULE::CheckEnclSph   ()
*
*************************************************************/
BOOL  m3dCAPSULE::CheckEnclSph   (class m3dSPHERE *pSph)
{
   ASSERT(FALSE); 
   return FALSE;
}

/*************************************************************
* void  m3dCAPSULE::GetCenter   ()
*
*************************************************************/
void  m3dCAPSULE::GetCenter   (m3dV *center) const
{
   ASSERT(FALSE); 
}

/*************************************************************
* void  m3dCAPSULE::GetFace  ()
*
*************************************************************/
void  m3dCAPSULE::GetFace  (int faceNmb, m3dPOLY *poly, m3dV *norm)
{
   ASSERT(FALSE); 
}

/*************************************************************
* void  m3dCAPSULE::GetFaceCenter  ()
*
*************************************************************/
void  m3dCAPSULE::GetFaceCenter  (int faceNmb, m3dV *center)
{
   ASSERT(FALSE); 
}

/*************************************************************
* void  m3dCAPSULE::Expand   ()
*
*************************************************************/
void  m3dCAPSULE::Expand   (float value)
{
   ASSERT(FALSE); 
}

/*************************************************************
* int   m3dCAPSULE::QualPlane   ()
*
*************************************************************/
int   m3dCAPSULE::QualPlane   (m3dV *planeOrg, m3dV *planeNorm)
{
   ASSERT(FALSE); 
   return 0;
}

/*************************************************************
* float m3dCAPSULE::GetSize  (void)
*
*************************************************************/
float m3dCAPSULE::GetSize  (void)
{
   ASSERT(FALSE); 
   return 0;
}


//
// End-of-file M3D_CAPSULE.CPP
//
